<!--  ERC-设备管理-设备台账页面-树形弹窗页面弹窗页面 -->
<template>
  <px-form ref="formRef" :model="model" label-position="right" :label-width="labelWidth" class="generic-form">
    <template v-for="field in config" :key="field.prop">
      <px-form-item :label="field.label" :prop="field.prop">
        <!-- choose Pxement‑Plus control dynamically -->
        <component :is="resolveComponent(field)" v-model="model[field.prop]" v-bind="field.props">
          <!-- for controls that need option slots, e.g., px-select -->
          <template v-if="isOptionType(field)">
            <px-option v-for="opt in optionMap[field.prop] || []" :key="opt.value" :label="opt.label" :value="opt.value" />
          </template>
        </component>
      </px-form-item>
    </template>
  </px-form>
</template>
<script setup lang="ts">
import { reactive, ref, watch, type Component } from "vue";
import { FieldConfig } from "./types";
import { type FormInstance, PxInput, PxInputNumber, PxSelect, PxDatePicker, PxSwitch, PxCheckboxGroup, PxRadioGroup } from "px-ui";
/**
 * 可扩展字段描述
 */

const props = withDefaults(
  defineProps<{
    /** 字段配置数组 */
    config: FieldConfig[];
    /** label 宽度，默认 120px */
    labelWidth?: string | number;
  }>(),
  { labelWidth: "120px" }
);

/**
 * defineModel 一行解决 modelValue + update:modelValue + 双向绑定
 * model 是 WritableComputedRef<Record<string, any>>
 */
const model = defineModel<Record<string, any>>();
const formRef = ref<InstanceType<typeof FormInstance>>();
function resolveComponent(field: FieldConfig): Component {
  switch (field.type) {
    case "input":
      return PxInput;
    case "number":
      return PxInputNumber;
    case "select":
      return PxSelect;
    case "date":
      return PxDatePicker;
    case "switch":
      return PxSwitch;
    case "radio":
      return PxRadioGroup;
    case "checkbox":
      return PxCheckboxGroup;
    default:
      return PxInput;
  }
}
const optionMap = reactive<Record<string, any[]>>({});
/** 加载静态 & 异步选项 */
async function loadOptions() {
  for (const field of props.config) {
    if (field.options) {
      optionMap[field.prop] = field.options;
    } else if (field.asyncOptions) {
      optionMap[field.prop] = []; // loading 占位
      try {
        const res = await field.asyncOptions();
        optionMap[field.prop] = res;
      } catch (e) {
        console.error(`加载 ${field.prop} 选项失败`, e);
      }
    }
  }
}

watch(
  () => props.config,
  () => {
    loadOptions();
  },
  { deep: true, immediate: true }
);
function isOptionType(field: FieldConfig) {
  return ["select", "radio", "checkbox"].includes(field.type);
}

defineExpose({
  validate: (cb?: (valid: boolean) => void) => formRef.value?.validate(cb),
  reset: () => formRef.value?.resetFields()
});
</script>
<style lang="scss" scoped>
.equip-dialog {
  .equip-dialog-footer {
    margin-top: 108px;
    text-align: right;
  }
}
</style>
